﻿/*
 * Created by SharpDevelop.
 * User: Masy Freddy
 * Date: 12/10/2011
 * Time: 5:38
 */

namespace ReaderXBMC
{
	using System;
	using System.Collections.Generic;
	using System.IO;
	using System.Text;
	using System.Xml.Serialization;

	using MetaVideoEditorEvolved.AddIn.AddInViews;
	using MetaVideoEditorEvolved.AddIn.Entity;
	using MetaVideoEditorEvolved.Helper;

	[System.AddIn.AddIn("XBMC Reader",
	                    Version = "1.0.0.0",
	                    Description = "XBMC Reader",
	                    Publisher = "Masy Freddy")]
	public class XBMC : ReaderView
	{
		private ConfigurationAddIn configurationAddIn;
		private const string MovieFileName = "movie.nfo",
		MoviePosterFileName = "movie.tbn",
		FanArtFileName = "fanart.jpg",
		ExtraFanArtDirectory = "extrafanart",
		SeriePoster = "folder.jpg",
		SerieFileName = "tvshow.nfo",
		EpisodePoster = "episode.tbn",
		EpisodeFileName = "episode.nfo",
		SeasonPoster = "season$$.tbn",
		ActorFileName = "folder.jpg",
		BannerFileName = "banner.jpg";
		
		public XBMC()
		{
			configurationAddIn = ConfigurationManager.Deserialize();
			
			if(configurationAddIn == null)
			{
				configurationAddIn = new ConfigurationAddIn()
				{
					UseExtraFanArt = true,
					TraceLevel = "Error"
				};
				
				ConfigurationManager.Serialize(configurationAddIn);
			}
			
			Tracer.TracerInstance.Level= string.IsNullOrEmpty(configurationAddIn.TraceLevel) ? TracerLevel.Error : (TracerLevel)Enum.Parse(typeof(TracerLevel), configurationAddIn.TraceLevel);
			Tracer.TracerInstance.FileName = "XbmcReader";
		}
		
		public override bool HasOption()
		{
			return true;
		}
		
		public override void ShowOption()
		{
			new Option(configurationAddIn).ShowDialog();
		}
		
		public override MetaVideoEditorEvolved.AddIn.Entity.Movie ReadMovie(string mediaLocation)
		{
			try
			{
				Tracer.TracerInstance.TraceInformation("XBMC Reader : Begin Read the media " + mediaLocation);
				movie movieXBMC = null;
				
				string metadataPath = string.Empty;
				
				if(File.Exists(Path.Combine(mediaLocation, MovieFileName)))
				{
					metadataPath = Path.Combine(mediaLocation, MovieFileName);
				}
				else
				{
					foreach (var element in Directory.GetFiles(mediaLocation, "*.nfo")) {
						metadataPath = element;
						break;
					}
				}
				
				if(!string.IsNullOrEmpty(metadataPath))
				{
					using (StreamReader sr = new StreamReader(metadataPath))
					{
						movieXBMC = new XmlSerializer(typeof(movie)).Deserialize(sr) as movie;
					}
				}
				
				if(movieXBMC != null)
				{
					Movie movieMVEE = new Movie();
					
					movieMVEE.Countries = movieXBMC.country == null ? new List<string>() : new List<string>(movieXBMC.country);
					
					int duration = 0;
					
					if(!string.IsNullOrEmpty(movieXBMC.runtime) && 
					   int.TryParse(movieXBMC.runtime, out duration))
					{
						movieMVEE.Duration = duration;
					}
					else
					{
						movieMVEE.Duration = 0;
					}
					
					movieMVEE.Genres = movieXBMC.genre == null ? new List<string>() : new List<string>(movieXBMC.genre);
					movieMVEE.MPAARating = movieXBMC.mpaa;
					movieMVEE.OriginalTitle = movieXBMC.originaltitle;
					movieMVEE.Overview = movieXBMC.plot;
					movieMVEE.Rating = string.IsNullOrEmpty(movieXBMC.rating) ? 0.0F : float.Parse(movieXBMC.rating.ToString());
					movieMVEE.SortTitle = movieXBMC.sorttitle;
					movieMVEE.Studios = movieXBMC.studio == null ? new List<string>() : new List<string>(movieXBMC.studio);
					movieMVEE.Title = movieXBMC.title;
					movieMVEE.Year = string.IsNullOrEmpty(movieXBMC.year) ? 0 : int.Parse(movieXBMC.year);
					
					movieMVEE.Posters = new List<Uri>();
					
					DirectoryInfo di= new DirectoryInfo(mediaLocation);
					
					if(File.Exists(mediaLocation))
					{
						di = di.Parent;
					}
					
					if(File.Exists(Path.Combine(di.FullName, MoviePosterFileName)))
					{
						movieMVEE.Posters.Add(new Uri(Path.Combine(di.FullName, MoviePosterFileName)));
					}
					else
					{
						foreach (var element in Directory.GetFiles(mediaLocation, "*.tbn")) {
							movieMVEE.Posters.Add(new Uri(element));
							break;
						}
					}
					
					movieMVEE.Trailers = new List<Trailer>();
					foreach (var element in di.GetFiles("movie-trailer*")) {
						movieMVEE.Trailers.Add(new Trailer
						                       {
						                       	DefaultPath = new Uri(element.FullName)
						                       });
					}
					
					movieMVEE.Backdrops = new List<Uri>();
					
					foreach (var element in Directory.GetFiles(di.FullName, "*fanart*")) {
						movieMVEE.Backdrops.Add(new Uri(element));
					}
					
					if(Directory.Exists(Path.Combine(di.FullName, ExtraFanArtDirectory)))
					{
						foreach (var element in new DirectoryInfo(Path.Combine(di.FullName, ExtraFanArtDirectory)).GetFiles("fanart*")) {
							movieMVEE.Backdrops.Add(new Uri(element.FullName));
						}
					}
					
					movieMVEE.CastMembers = new List<CastMember>();
					
					if(movieXBMC.actor != null)
					{
						foreach (var element in movieXBMC.actor) {
							movieMVEE.CastMembers.Add(new CastMember
							                          {
							                          	FullName = element.name.Replace("\"", string.Empty).Replace("\t", string.Empty),
							                          	Role = element.role,
							                          	Activity = "Actor",
							                          	Picture = ReadActor(mediaLocation, element.name.Replace("\"", string.Empty).Replace("\t", string.Empty))
							                          });
						}
					}
					
					if(movieXBMC.director != null)
					{
						foreach (var element in movieXBMC.director) {
							movieMVEE.CastMembers.Add(new CastMember
							                          {
							                          	FullName = element,
							                          	Activity = "Director"
							                          });
						}
					}
					
					Tracer.TracerInstance.TraceInformation("XBMC Reader : End Read the media " + mediaLocation);
					
					return movieMVEE;
				}
				
				return null;
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(string.Format("Exception is occured for {0} : {1}", mediaLocation), ex);
				throw;
			}
		}
		
		public override MetaVideoEditorEvolved.AddIn.Entity.Serie ReadSerie(string mediaLocation)
		{
			try
			{
				tvshow serieXBMC = null;
				
				string metadataPath = Path.Combine(mediaLocation, SerieFileName);
				
				if(File.Exists(metadataPath))
				{
					using (StreamReader sr = new StreamReader(metadataPath))
					{
						serieXBMC = new XmlSerializer(typeof(tvshow)).Deserialize(sr) as tvshow;
					}
				}
				
				if(serieXBMC != null)
				{
					Serie serieMVEE = new Serie();
					
					//serieMVEE.Duration = int.Parse(serieXBMC.runtime.ToString());
					serieMVEE.Genres = serieXBMC.genre == null ? new List<string>() : new List<string>(serieXBMC.genre);
					serieMVEE.Id = serieXBMC.id;
					serieMVEE.Name = serieXBMC.title;
					serieMVEE.Overview = serieXBMC.plot;
					serieMVEE.Rating = string.IsNullOrEmpty(serieXBMC.rating) ? 0.0F : float.Parse(serieXBMC.rating);
					serieMVEE.Studios =  serieXBMC.studio == null ? new List<string>() : new List<string>(serieXBMC.studio);
					serieMVEE.Year = string.IsNullOrEmpty(serieXBMC.year) ? 0 : int.Parse(serieXBMC.year);
					
					serieMVEE.Posters = new List<Uri>();
					DirectoryInfo di= new DirectoryInfo(mediaLocation);
					
					if(File.Exists(mediaLocation))
					{
						di = di.Parent;
					}
					
					if(File.Exists(Path.Combine(di.FullName, SeriePoster)))
					{
						serieMVEE.Posters.Add(new Uri(Path.Combine(di.FullName, SeriePoster)));
					}
					
					serieMVEE.Backdrops = new List<Uri>();
					if(File.Exists(Path.Combine(di.FullName, FanArtFileName)))
					{
						serieMVEE.Backdrops.Add(new Uri(Path.Combine(di.FullName, FanArtFileName)));
					}
					
					if(Directory.Exists(Path.Combine(di.FullName, ExtraFanArtDirectory)))
					{
						foreach (var element in new DirectoryInfo(Path.Combine(di.FullName, ExtraFanArtDirectory)).GetFiles("fanart*")) {
							serieMVEE.Backdrops.Add(new Uri(element.FullName));
						}
					}
					
					serieMVEE.CastMembers = new List<CastMember>();
					if(serieXBMC.actor != null)
					{
						foreach (var element in serieXBMC.actor) {
							serieMVEE.CastMembers.Add(new CastMember
							                          {
							                          	FullName = element.name,
							                          	Activity = "Actor",
							                          	Role = element.role,
							                          	Picture = ReadActor(mediaLocation, element.name)
							                          });
						}
					}
					
					if(serieXBMC.director != null)
					{
						foreach (var element in serieXBMC.director) {
							serieMVEE.CastMembers.Add(new CastMember
							                          {
							                          	FullName = element,
							                          	Activity = "Director",
							                          });
						}
					}
					
					serieMVEE.Graphicals = new List<Uri>();
					if(File.Exists(Path.Combine(di.FullName, BannerFileName)))
					{
						serieMVEE.Graphicals.Add(new Uri(Path.Combine(di.FullName, BannerFileName)));
					}
					
					return serieMVEE;
				}
				
				return null;
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(string.Format("Exception in XBMC ReadSerie mediaLocation={0}", mediaLocation), ex);
				throw;
			}
		}
		
		public override MetaVideoEditorEvolved.AddIn.Entity.Season ReadSeason(string mediaLocation)
		{
			try
			{
				DirectoryInfo di= new DirectoryInfo(mediaLocation);
				
				if(File.Exists(mediaLocation))
				{
					di = di.Parent;
				}
				
				var seasonNumberSplit = di.Name.Split(' ');
				
				string seasonNumber = seasonNumberSplit.Length > 1 ? seasonNumberSplit[1] : "0";
				
				Season season = new Season()
				{
					Images = new List<Uri>(),
					Number = int.Parse(seasonNumber)
				};
				
				if(File.Exists(Path.Combine(di.Parent.FullName, SeasonPoster.Replace("$$", seasonNumber.PadLeft(2,'0')))))
				{
					season.Images.Add(new Uri(Path.Combine(di.Parent.FullName, SeasonPoster.Replace("$$", seasonNumber.PadLeft(2,'0')))));
				}
				
				return season;
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(string.Format("Exception XBMC ReadSeason mediaLocation={0}", mediaLocation), ex);
				throw;
			}
		}
		
		public override MetaVideoEditorEvolved.AddIn.Entity.Episode ReadEpisode(string mediaLocation)
		{
			try
			{
				episodedetails episodeXBMC = null;
				
				FileInfo fi = new FileInfo(mediaLocation);
				
				string metadataPath = Path.Combine( fi.DirectoryName, fi.Name.Replace(fi.Extension, string.Empty) + ".nfo");
				
				if(File.Exists(metadataPath))
				{
					using (StreamReader sr = new StreamReader(metadataPath))
					{
						episodeXBMC = new XmlSerializer(typeof(episodedetails)).Deserialize(sr) as episodedetails;
					}
				}
				
				if(episodeXBMC != null)
				{
					Episode episode =new Episode();
					
					
					episode.Name = episodeXBMC.title;
					episode.Number = string.IsNullOrEmpty(episodeXBMC.episode) ? 0 : int.Parse(episodeXBMC.episode);
					episode.Overview = episodeXBMC.plot;
					episode.Rating = string.IsNullOrEmpty(episodeXBMC.rating) ? 0.0F : float.Parse(episodeXBMC.rating);
					episode.SeasonNumber = string.IsNullOrEmpty(episodeXBMC.season) ? 0 : int.Parse(episodeXBMC.season);
					episode.FirstAired = episodeXBMC.aired;
					
					episode.Directors = new List<string>();
					if(episodeXBMC.director != null)
					{
						foreach (var element in episodeXBMC.director) {
							episode.Directors.Add(element);
						}
					}
					
					episode.GuestStars = new List<string>();
					if(episodeXBMC.actor != null)
					{
						foreach (var element in episodeXBMC.actor) {
							episode.GuestStars.Add(element.name);
						}
					}
					
					episode.Writers = new List<string>();

					episode.Images = new List<Uri>();
					
					DirectoryInfo di= new DirectoryInfo(mediaLocation);
					
					if(File.Exists(mediaLocation))
					{
						di = di.Parent;
					}
					
					if(File.Exists(Path.Combine(di.FullName, fi.Name.Replace(fi.Extension, string.Empty) + ".tbn")))
					{
						episode.Images.Add(new Uri(Path.Combine(di.FullName, fi.Name.Replace(fi.Extension, string.Empty) + ".tbn")));
					}
					
					return episode;
				}
				
				return null;
			}
			catch(Exception ex)
			{
				Tracer.TracerInstance.TraceError(string.Format("Exception XBMC ReadEpisode mediaLocation={0}", mediaLocation), ex);
				throw;
			}
		}
		
		private Uri ReadActor(string mediaLocation, string actorName)
		{
			DirectoryInfo di= new DirectoryInfo(mediaLocation);
			
			if(File.Exists(mediaLocation))
			{
				di = di.Parent;
			}
			
			if(File.Exists(Path.Combine(di.FullName, ".actor" , actorName.Replace(' ', '_') + ".tbn")))
			{
				return new Uri(Path.Combine(di.FullName, ".actor" , actorName.Replace(' ', '_') + ".tbn"));
			}
			
			return null;
		}
	}
}